// 封装套接字 ---- 采用 : 模版方法设计模式 !

// 什么是模版方法类设计模式 ? -- *** 还是继承多态 ***
#if 0  
// 就是代码相似度高 , 通过多态的方式实现 , 基类到子类的转化 
// Socket 类 , Socket 包含 : UDP 和 TCP , 二者有很多相似的地方
// 所以 , 通过实现一个基类来实现 , 外部只用 Socket 就能创建 UDP 和 TCP

就像有一个模版一样 , 创建不同的协议都是一样的调用
虚函数方法都是所以子类共享的 , 都可以调用 !

#endif

#include <iostream>

#pragma once
namespace SocketModel
{
    // 这是一个基类 , 通过多态外部可以通过其类创建 TCP , UDP
    // 实现多态的前提是继承 , 并且要重写基类的虚函数
    // 这里定义纯虚函数 , 让基类中不用具体实现 , 继承多态时具体实现
    class Socket
    {
    public:
        Socket() {}
        virtual ~Socket() {}

        // 1 . UDP和TCP 都要创建套接字吧
        virtual void SocketOrDie() = 0;
        // 2 . UDP和TCP 都要绑定吧
        virtual void BindOrDie() = 0;
    };

    // UDP 继承基类 - 子类就要重写虚函数
    class UDP : public Socket
    {
    public:
        UDP() {}
        // 无论子类析构有无 virtual 都与基类的虚析构构成重写 !
        ~UDP() {}

        // 1. 重写 SocketOrDie()
        void SocketOrDie() override
        {
            std::cout << "我是创建套接字 -- UDP" << std::endl;
        }

        // 2. 重写 BindOrDie()
        void BindOrDie() override
        {
            std::cout << "我是绑定网络信息 -- UDP" << std::endl;
        }
    };

    // TCP 继承基类 - 子类就要重写虚函数
    class TCP : public Socket
    {
    public:
        TCP() {}
        // 无论子类析构有无 virtual 都与基类的虚析构构成重写 !
        virtual ~TCP() {}

        // 1. 重写 SocketOrDie()
        void SocketOrDie() override
        {
            std::cout << "我是创建套接字 -- TCP" << std::endl;
        }

        // 2. 重写 BindOrDie()
        void BindOrDie() override
        {
            std::cout << "我是绑定网络信息 -- TCP" << std::endl;
        }
    };
};